#ifndef PSFTrajectoryPoint_h
#define PSFTrajectoryPoint_h 1

#include "globals.hh"
#include "G4Allocator.hh"
#include "G4StepStatus.hh"
#include "G4ThreeVector.hh"
#include "G4TrajectoryPoint.hh"

class G4Track;
class G4Step;
class G4VProcess;

class PSFTrajectoryPoint : public G4TrajectoryPoint
{
public:
  PSFTrajectoryPoint() = default;
  PSFTrajectoryPoint(const G4Track *);
  PSFTrajectoryPoint(const G4Step *);
  PSFTrajectoryPoint(const PSFTrajectoryPoint &right);
  ~PSFTrajectoryPoint() override = default;

  inline void *operator new(size_t);
  inline void operator delete(void *aTrajectoryPoint);
  inline G4bool operator==(const PSFTrajectoryPoint &right) const
  {
    return (this == &right);
  };

  inline G4double GetTime() const { return fTime; };
  inline const G4ThreeVector GetMomentum() const { return fMomentum; };
  inline G4StepStatus GetStepStatus() const { return fStepStatus; };
  inline G4String GetVolumeName() const { return fVolumeName; };

  const std::map<G4String, G4AttDef> *GetAttDefs() const override;
  std::vector<G4AttValue> *CreateAttValues() const override;

private:
  G4double fTime = 0.;
  G4ThreeVector fMomentum;
  G4StepStatus fStepStatus = fUndefined;
  G4String fVolumeName;
};

extern G4ThreadLocal G4Allocator<PSFTrajectoryPoint> *PSFTrajPointAllocator;

inline void *PSFTrajectoryPoint::operator new(size_t)
{
  if (!PSFTrajPointAllocator)
    PSFTrajPointAllocator = new G4Allocator<PSFTrajectoryPoint>;
  return (void *)PSFTrajPointAllocator->MallocSingle();
}

inline void PSFTrajectoryPoint::operator delete(void *aTrajectoryPoint)
{
  PSFTrajPointAllocator->FreeSingle((PSFTrajectoryPoint *)aTrajectoryPoint);
}

#endif
